import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';

import 'package:forui/forui.dart';
import 'package:forui/src/widgets/select_menu_tile.dart';

/// A marker interface which denotes that mixed-in widgets can be used in a [FTileGroup].
mixin FTileMixin on Widget {
  /// {@macro forui.widgets.FSelectMenuTile.new}
  ///
  /// This function is a shorthand for [FSelectMenuTile.new].
  static FSelectMenuTile<T> selectMenu<T>({
    required Widget title,
    required List<FSelectTile<T>> menu,
    FSelectMenuTileController<T>? selectController,
    FPopoverController? popoverController,
    ScrollController? scrollController,
    FSelectMenuTileStyle Function(FSelectMenuTileStyle style)? style,
    double? cacheExtent,
    double maxHeight = .infinity,
    DragStartBehavior dragStartBehavior = .start,
    ScrollPhysics physics = const ClampingScrollPhysics(),
    FItemDivider divider = .full,
    AlignmentGeometry menuAnchor = .topRight,
    AlignmentGeometry tileAnchor = .bottomRight,
    FPortalSpacing spacing = const .spacing(4),
    FPortalOverflow overflow = .flip,
    Offset offset = .zero,
    FPopoverHideRegion hideRegion = .excludeChild,
    VoidCallback? onTapHide,
    bool autoHide = true,
    Widget? label,
    Widget? description,
    bool autofocus = false,
    FocusScopeNode? focusNode,
    ValueChanged<bool>? onFocusChange,
    TraversalEdgeBehavior? traversalEdgeBehavior,
    String? barrierSemanticsLabel,
    bool barrierSemanticsDismissible = true,
    String? semanticsLabel,
    Widget? prefix,
    Widget? subtitle,
    ValueWidgetBuilder<Set<T>> detailsBuilder = defaultSelectMenuTileBuilder,
    Widget? details,
    Widget? suffix,
    Map<ShortcutActivator, Intent>? shortcuts,
    Map<Type, Action<Intent>>? actions,
    ValueChanged<Set<T>>? onChange,
    ValueChanged<(T, bool)>? onSelect,
    Widget Function(BuildContext context, String message) errorBuilder = FFormFieldProperties.defaultErrorBuilder,
    T? initialValue,
    FormFieldSetter<Set<T>>? onSaved,
    VoidCallback? onReset,
    FormFieldValidator<Set<T>>? validator,
    String? forceErrorText,
    bool enabled = true,
    AutovalidateMode? autovalidateMode,
    String? restorationId,
    Key? key,
  }) => .new(
    title: title,
    menu: menu,
    selectController: selectController,
    popoverController: popoverController,
    scrollController: scrollController,
    style: style,
    cacheExtent: cacheExtent,
    maxHeight: maxHeight,
    dragStartBehavior: dragStartBehavior,
    physics: physics,
    divider: divider,
    menuAnchor: menuAnchor,
    tileAnchor: tileAnchor,
    spacing: spacing,
    overflow: overflow,
    offset: offset,
    hideRegion: hideRegion,
    onTapHide: onTapHide,
    autoHide: autoHide,
    label: label,
    description: description,
    autofocus: autofocus,
    focusNode: focusNode,
    onFocusChange: onFocusChange,
    traversalEdgeBehavior: traversalEdgeBehavior,
    barrierSemanticsLabel: barrierSemanticsLabel,
    barrierSemanticsDismissible: barrierSemanticsDismissible,
    semanticsLabel: semanticsLabel,
    prefix: prefix,
    subtitle: subtitle,
    detailsBuilder: detailsBuilder,
    details: details,
    suffix: suffix,
    shortcuts: shortcuts,
    actions: actions,
    onChange: onChange,
    onSelect: onSelect,
    errorBuilder: errorBuilder,
    initialValue: initialValue,
    onSaved: onSaved,
    onReset: onReset,
    validator: validator,
    forceErrorText: forceErrorText,
    enabled: enabled,
    autovalidateMode: autovalidateMode,
    restorationId: restorationId,
    key: key,
  );

  /// {@macro forui.widgets.FSelectMenuTile.fromMap}
  ///
  /// This function is a shorthand for [FSelectMenuTile.fromMap].
  static FSelectMenuTile<T> selectMenuFromMap<T>(
    Map<String, T> menu, {
    required Text title,
    FSelectMenuTileController<T>? selectController,
    FPopoverController? popoverController,
    ScrollController? scrollController,
    FSelectMenuTileStyle Function(FSelectMenuTileStyle style)? style,
    double? cacheExtent,
    double maxHeight = .infinity,
    DragStartBehavior dragStartBehavior = .start,
    ScrollPhysics physics = const ClampingScrollPhysics(),
    FItemDivider divider = .full,
    AlignmentGeometry menuAnchor = .topRight,
    AlignmentGeometry tileAnchor = .bottomRight,
    FPortalSpacing spacing = const .spacing(4),
    FPortalOverflow overflow = .flip,
    Offset offset = .zero,
    FPopoverHideRegion hideRegion = .excludeChild,
    VoidCallback? onTapHide,
    bool autoHide = true,
    Widget? label,
    Widget? description,
    bool autofocus = false,
    FocusScopeNode? focusNode,
    ValueChanged<bool>? onFocusChange,
    TraversalEdgeBehavior? traversalEdgeBehavior,
    String? barrierSemanticsLabel,
    bool barrierSemanticsDismissible = true,
    String? semanticsLabel,
    Widget? prefix,
    Widget? subtitle,
    ValueWidgetBuilder<Set<T>> detailsBuilder = defaultSelectMenuTileBuilder,
    Widget? details,
    Widget? suffix,
    Map<ShortcutActivator, Intent>? shortcuts,
    Map<Type, Action<Intent>>? actions,
    ValueChanged<Set<T>>? onChange,
    ValueChanged<(T, bool)>? onSelect,
    Widget Function(BuildContext context, String message) errorBuilder = FFormFieldProperties.defaultErrorBuilder,
    T? initialValue,
    FormFieldSetter<Set<T>>? onSaved,
    VoidCallback? onReset,
    FormFieldValidator<Set<T>>? validator,
    String? forceErrorText,
    bool enabled = true,
    AutovalidateMode? autovalidateMode,
    String? restorationId,
    Key? key,
  }) => .fromMap(
    menu,
    title: title,
    selectController: selectController,
    popoverController: popoverController,
    scrollController: scrollController,
    style: style,
    cacheExtent: cacheExtent,
    maxHeight: maxHeight,
    dragStartBehavior: dragStartBehavior,
    physics: physics,
    divider: divider,
    menuAnchor: menuAnchor,
    tileAnchor: tileAnchor,
    spacing: spacing,
    overflow: overflow,
    offset: offset,
    hideRegion: hideRegion,
    onTapHide: onTapHide,
    autoHide: autoHide,
    label: label,
    description: description,
    autofocus: autofocus,
    focusNode: focusNode,
    onFocusChange: onFocusChange,
    traversalEdgeBehavior: traversalEdgeBehavior,
    barrierSemanticsLabel: barrierSemanticsLabel,
    barrierSemanticsDismissible: barrierSemanticsDismissible,
    semanticsLabel: semanticsLabel,
    prefix: prefix,
    subtitle: subtitle,
    detailsBuilder: detailsBuilder,
    details: details,
    suffix: suffix,
    shortcuts: shortcuts,
    actions: actions,
    onChange: onChange,
    onSelect: onSelect,
    errorBuilder: errorBuilder,
    initialValue: initialValue,
    onSaved: onSaved,
    onReset: onReset,
    validator: validator,
    forceErrorText: forceErrorText,
    enabled: enabled,
    autovalidateMode: autovalidateMode,
    restorationId: restorationId,
    key: key,
  );

  /// {@macro forui.widgets.FSelectMenuTile.builder}
  ///
  /// This function is a shorthand for [FSelectMenuTile.builder].
  static FSelectMenuTile<T> selectMenuBuilder<T>({
    required Widget title,
    required FSelectTile<T>? Function(BuildContext context, int index) menuBuilder,
    int? count,
    FSelectMenuTileController<T>? selectController,
    FPopoverController? popoverController,
    ScrollController? scrollController,
    FSelectMenuTileStyle Function(FSelectMenuTileStyle style)? style,
    double? cacheExtent,
    double maxHeight = .infinity,
    DragStartBehavior dragStartBehavior = .start,
    ScrollPhysics physics = const ClampingScrollPhysics(),
    FItemDivider divider = .full,
    AlignmentGeometry menuAnchor = .topRight,
    AlignmentGeometry tileAnchor = .bottomRight,
    FPortalSpacing spacing = const .spacing(4),
    FPortalOverflow overflow = .flip,
    Offset offset = .zero,
    FPopoverHideRegion hideRegion = .excludeChild,
    VoidCallback? onTapHide,
    bool autoHide = true,
    Widget? label,
    Widget? description,
    bool autofocus = false,
    FocusScopeNode? focusNode,
    ValueChanged<bool>? onFocusChange,
    TraversalEdgeBehavior? traversalEdgeBehavior,
    String? barrierSemanticsLabel,
    bool barrierSemanticsDismissible = true,
    String? semanticsLabel,
    Widget? prefix,
    Widget? subtitle,
    ValueWidgetBuilder<Set<T>> detailsBuilder = defaultSelectMenuTileBuilder,
    Widget? details,
    Widget? suffix,
    Map<ShortcutActivator, Intent>? shortcuts,
    Map<Type, Action<Intent>>? actions,
    ValueChanged<Set<T>>? onChange,
    ValueChanged<(T, bool)>? onSelect,
    Widget Function(BuildContext context, String message) errorBuilder = FFormFieldProperties.defaultErrorBuilder,
    T? initialValue,
    FormFieldSetter<Set<T>>? onSaved,
    VoidCallback? onReset,
    FormFieldValidator<Set<T>>? validator,
    String? forceErrorText,
    bool enabled = true,
    AutovalidateMode? autovalidateMode,
    String? restorationId,
    Key? key,
  }) => .builder(
    title: title,
    menuBuilder: menuBuilder,
    count: count,
    selectController: selectController,
    popoverController: popoverController,
    scrollController: scrollController,
    style: style,
    cacheExtent: cacheExtent,
    maxHeight: maxHeight,
    dragStartBehavior: dragStartBehavior,
    physics: physics,
    divider: divider,
    menuAnchor: menuAnchor,
    tileAnchor: tileAnchor,
    spacing: spacing,
    overflow: overflow,
    offset: offset,
    hideRegion: hideRegion,
    onTapHide: onTapHide,
    autoHide: autoHide,
    label: label,
    description: description,
    autofocus: autofocus,
    focusNode: focusNode,
    onFocusChange: onFocusChange,
    traversalEdgeBehavior: traversalEdgeBehavior,
    barrierSemanticsLabel: barrierSemanticsLabel,
    barrierSemanticsDismissible: barrierSemanticsDismissible,
    semanticsLabel: semanticsLabel,
    prefix: prefix,
    subtitle: subtitle,
    detailsBuilder: detailsBuilder,
    details: details,
    suffix: suffix,
    shortcuts: shortcuts,
    actions: actions,
    onChange: onChange,
    onSelect: onSelect,
    errorBuilder: errorBuilder,
    initialValue: initialValue,
    onSaved: onSaved,
    onReset: onReset,
    validator: validator,
    forceErrorText: forceErrorText,
    enabled: enabled,
    autovalidateMode: autovalidateMode,
    restorationId: restorationId,
    key: key,
  );

  /// {@macro forui.widgets.FTile.new}
  ///
  /// This function is a shorthand for [FTile.new].
  static FTile tile({
    required Widget title,
    FItemStyle Function(FItemStyle style)? style,
    bool? enabled,
    bool selected = false,
    String? semanticsLabel,
    bool autofocus = false,
    FocusNode? focusNode,
    ValueChanged<bool>? onFocusChange,
    ValueChanged<bool>? onHoverChange,
    ValueChanged<FWidgetStatesDelta>? onStateChange,
    VoidCallback? onPress,
    VoidCallback? onLongPress,
    VoidCallback? onSecondaryPress,
    VoidCallback? onSecondaryLongPress,
    Map<ShortcutActivator, Intent>? shortcuts,
    Map<Type, Action<Intent>>? actions,
    Widget? prefix,
    Widget? subtitle,
    Widget? details,
    Widget? suffix,
    Key? key,
  }) => .new(
    title: title,
    style: style,
    enabled: enabled,
    selected: selected,
    semanticsLabel: semanticsLabel,
    autofocus: autofocus,
    focusNode: focusNode,
    onFocusChange: onFocusChange,
    onHoverChange: onHoverChange,
    onStateChange: onStateChange,
    onPress: onPress,
    onLongPress: onLongPress,
    onSecondaryPress: onSecondaryPress,
    onSecondaryLongPress: onSecondaryLongPress,
    shortcuts: shortcuts,
    actions: actions,
    prefix: prefix,
    subtitle: subtitle,
    details: details,
    suffix: suffix,
    key: key,
  );

  /// {@macro forui.widgets.FTile.raw}
  ///
  /// This function is a shorthand for [FTile.raw].
  static FTile raw({
    required Widget child,
    FItemStyle Function(FItemStyle style)? style,
    bool? enabled,
    bool selected = false,
    String? semanticsLabel,
    bool autofocus = false,
    FocusNode? focusNode,
    ValueChanged<bool>? onFocusChange,
    ValueChanged<bool>? onHoverChange,
    ValueChanged<FWidgetStatesDelta>? onStateChange,
    VoidCallback? onPress,
    VoidCallback? onLongPress,
    VoidCallback? onSecondaryPress,
    VoidCallback? onSecondaryLongPress,
    Map<ShortcutActivator, Intent>? shortcuts,
    Map<Type, Action<Intent>>? actions,
    Widget? prefix,
    Key? key,
  }) => .raw(
    style: style,
    enabled: enabled,
    selected: selected,
    semanticsLabel: semanticsLabel,
    autofocus: autofocus,
    focusNode: focusNode,
    onFocusChange: onFocusChange,
    onHoverChange: onHoverChange,
    onStateChange: onStateChange,
    onPress: onPress,
    onLongPress: onLongPress,
    onSecondaryPress: onSecondaryPress,
    onSecondaryLongPress: onSecondaryLongPress,
    shortcuts: shortcuts,
    actions: actions,
    prefix: prefix,
    key: key,
    child: child,
  );
}
